#include "StdAfx.h"
#include "AdditiveSynthFactory.h"
#include <sstream>

using namespace std;

CAdditiveSynthFactory::CAdditiveSynthFactory(void)
{
	m_amps.clear();
	m_ampsfade.clear();

	m_attack = 0.05;
    m_release = 0.05;
	m_decay = 0.05;
	m_attackFactor = 1.15;

	m_vibrato = false;
	m_vibratofreq = 0.;
	m_modulation = 0.;
}


CAdditiveSynthFactory::~CAdditiveSynthFactory(void)
{
}

void CAdditiveSynthFactory::Reset()
{
	m_amps.clear();
	m_ampsfade.clear();

	m_attack = 0.05;
    m_release = 0.05;
	m_decay = 0.05;
	m_attackFactor = 1.15;

	m_vibrato = false;
	m_vibratofreq = 0.;
	m_modulation = 0.;
}

CAdditiveSynthInstrument *CAdditiveSynthFactory::CreateInstrument()
{
    CAdditiveSynthInstrument *instrument = new CAdditiveSynthInstrument();

	instrument->SetADSR(m_attack, m_decay, m_release, m_attackFactor);
	instrument->SetVibrato(m_vibrato, m_vibratofreq, m_modulation);

	for(int i=0;  i<m_amps.size();  i++)
    {
        instrument->SetAmplitude(i, m_amps[i]);
    }

	for(int i=0; i<m_ampsfade.size(); i++)
	{
		instrument->SetAmplitudeFade(i, m_ampsfade[i]);
	}

    return instrument;
}


void CAdditiveSynthFactory::SetNote(CNote *note)
{
	m_amps.clear();
	m_ampsfade.clear();

    // Get a list of all attribute nodes and the
    // length of that list
    CComPtr<IXMLDOMNamedNodeMap> attributes;
    note->Node()->get_attributes(&attributes);
    long len;
    attributes->get_length(&len);

    // Loop over the list of attributes
    for(int i=0;  i<len;  i++)
    {
        // Get attribute i
        CComPtr<IXMLDOMNode> attrib;
        attributes->get_item(i, &attrib);

        // Get the name of the attribute
        CComBSTR name;
        attrib->get_nodeName(&name);

        CComVariant value;
        attrib->get_nodeValue(&value);

		if(name == "harmonics")
        {
            wstringstream inputStream(value.bstrVal);
			double amplitude = 0.;

			while (!inputStream.eof())
			{
				inputStream >> amplitude;
				m_amps.push_back(amplitude);
			}
        }
		else if (name == "adsr")
		{
			wstringstream inputStream(value.bstrVal);

			while (!inputStream.eof())
			{
				inputStream >> m_attack;
				inputStream >> m_decay;
				inputStream >> m_release;
			}
		}
		else if (name == "harmonicfade")
		{
			wstringstream inputStream(value.bstrVal);
			double amplitude = 0.;

			while (!inputStream.eof())
			{
				inputStream >> amplitude;
				m_ampsfade.push_back(amplitude);
			}
		}
		else if (name == "vibrato")
		{
			m_vibrato = true;
			wstringstream inputStream(value.bstrVal);

			while (!inputStream.eof())
			{
				inputStream >> m_vibratofreq;
				inputStream >> m_modulation;
			}
		}
    }

}